"""Minimal Account page

Compact, import-safe AccountPage for development. Keeps behavior small to
avoid import-time errors while providing basic profile and orders view.
"""

import tkinter as tk
from tkinter import ttk, messagebox
import os
import customtkinter
from ui.pages.scrollable_page import ScrollablePage
from core.services.data_manager import DataManager
from core.utils.image_utils import load_thumbnail, load_circular_thumbnail
from core.utils.i18n import t
from ui.styles.theme import Theme


class AccountPage(ScrollablePage):
    """Minimal Account page: shows username/email and orders."""

    def create_widgets(self):
        content = self.scrollable_frame
        # Top header with avatar + user info
        header = customtkinter.CTkFrame(content, fg_color="transparent")
        header.pack(fill='x', padx=20, pady=(0, 15))

        # Left: back button + logo/title area
        self.back_btn = customtkinter.CTkButton(
            header, 
            text=t("common.back"), 
            command=lambda: self.controller.show_page('ProductPage'),
            width=80,
            height=32,
            font=('Arial', 11)
        )
        self.back_btn.pack(side='left', padx=(0, 12))
        
        self.logo = customtkinter.CTkLabel(
            header, 
            text=t("account.logo"), 
            font=('Arial', 18, 'bold'), 
            text_color=Theme.get_color('accent')
        )
        self.logo.pack(side='left')

        # Middle: search placeholder (kept minimal)
        middle = customtkinter.CTkFrame(header, fg_color="transparent")
        middle.pack(side='left', expand=True, fill='x', padx=20)

        # Right: user toolbar (cart, orders, account)
        self.user_area = customtkinter.CTkFrame(header, fg_color="transparent")
        self.user_area.pack(side='right')

        self.cart_btn = customtkinter.CTkButton(
            self.user_area, 
            text=t('product.cart'), 
            command=lambda: self.controller.show_page('ProductPage'),
            width=100,
            height=32,
            font=('Arial', 11)
        )
        self.cart_btn.pack(side='left', padx=6)
        
        self.orders_btn = customtkinter.CTkButton(
            self.user_area, 
            text=t('product.orders'), 
            command=lambda: self.controller.show_page('OrdersPage'),
            width=100,
            height=32,
            font=('Arial', 11)
        )
        self.orders_btn.pack(side='left', padx=6)
        
        self.profile_btn = customtkinter.CTkButton(
            self.user_area, 
            text=t('product.account'), 
            command=lambda: None, 
            state='disabled',
            width=100,
            height=32,
            font=('Arial', 11)
        )
        self.profile_btn.pack(side='left', padx=6)

        # User info + avatar area (centered)
        info_frame = customtkinter.CTkFrame(content, fg_color=("gray95", "gray20"), corner_radius=15)
        info_frame.pack(fill='both', expand=True, padx=50, pady=(0, 30))

        # Create a centered column (use pack so it participates in layout inside the scrollable frame)
        column = customtkinter.CTkFrame(info_frame, fg_color="transparent")
        column.pack(anchor='center', pady=40)

        self.avatar_canvas = tk.Canvas(column, width=120, height=120, bd=0, highlightthickness=0, bg=Theme.get_color('bg_primary'))
        self.avatar_canvas.pack(pady=(4, 20))
        # draw a simple placeholder so the area is not visually empty
        self.avatar_canvas.create_oval(5, 5, 115, 115, outline='#ddd', width=2)
        self.avatar_canvas.create_text(60, 60, text='👤', font=('Arial', 40), fill=Theme.get_color('fg_tertiary'))

        self.name_label = customtkinter.CTkLabel(
            column, 
            text=t('account.guest'), 
            font=('Arial', 18, 'bold'),
            text_color=Theme.get_color('fg_primary')
        )
        self.name_label.pack()
        
        self.email_label = customtkinter.CTkLabel(
            column, 
            text=t('account.not_logged_in'),
            text_color=Theme.get_color('fg_tertiary'),
            font=('Arial', 12)
        )
        self.email_label.pack(pady=(8, 30))

        # Vertical centered buttons
        self.btns = customtkinter.CTkFrame(column, fg_color="transparent")
        self.btns.pack()
        
        self.edit_profile_btn = customtkinter.CTkButton(
            self.btns, 
            text=t('account.edit_profile'), 
            width=200, 
            height=40,
            command=self.edit_profile,
            font=('Arial', 13, "bold"),
            fg_color=Theme.get_color('accent'),
            hover_color=Theme.get_color('accent_hover'),
            corner_radius=10
        )
        self.edit_profile_btn.pack(pady=8)
        
        self.upload_avatar_btn = customtkinter.CTkButton(
            self.btns, 
            text=t('account.upload_avatar'), 
            width=200,
            height=40,
            command=self.upload_avatar,
            font=('Arial', 13),
            fg_color=("gray70", "gray30"),
            hover_color=("gray60", "gray40"),
            corner_radius=10
        )
        self.upload_avatar_btn.pack(pady=8)
        
        self.settings_btn = customtkinter.CTkButton(
            self.btns, 
            text=t('account.settings'), 
            width=200,
            height=40,
            command=self.open_settings,
            font=('Arial', 13),
            fg_color=("gray70", "gray30"),
            hover_color=("gray60", "gray40"),
            corner_radius=10
        )
        self.settings_btn.pack(pady=8)

        # Keep minimal: no orders list area here (replaced by toolbar buttons)

    def edit_profile(self):
        if not self.controller.auth_service.is_logged_in():
            messagebox.showwarning(t("account.actions.not_logged_in_title"), t("account.actions.login_required_profile"))
            self.controller.show_page('LoginPage')
            return

        user = self.controller.auth_service.current_user
        win = customtkinter.CTkToplevel(self)
        win.title('Edit Profile')
        win.geometry('500x400')
        
        # 主容器
        frm = customtkinter.CTkFrame(win, fg_color="transparent")
        frm.pack(fill='both', expand=True, padx=30, pady=30)
        
        # 标题
        title = customtkinter.CTkLabel(
            frm,
            text='Edit Profile',
            font=('Arial', 20, 'bold'),
            text_color=Theme.get_color('fg_primary')
        )
        title.pack(pady=(0, 30))
        
        # 内容容器
        content_frame = customtkinter.CTkFrame(frm, fg_color="transparent")
        content_frame.pack(fill='both', expand=True)
        
        # 左侧：表单
        form_frame = customtkinter.CTkFrame(content_frame, fg_color="transparent")
        form_frame.pack(side='left', fill='both', expand=True, padx=(0, 20))
        
        customtkinter.CTkLabel(form_frame, text='Username:', font=('Arial', 12)).pack(anchor='w', pady=(0, 5))
        name_var = tk.StringVar(value=getattr(user, 'username', ''))
        name_entry = customtkinter.CTkEntry(form_frame, textvariable=name_var, width=250, height=35, font=('Arial', 12))
        name_entry.pack(pady=(0, 15))

        customtkinter.CTkLabel(form_frame, text='Email:', font=('Arial', 12)).pack(anchor='w', pady=(0, 5))
        email_var = tk.StringVar(value=getattr(user, 'email', ''))
        email_entry = customtkinter.CTkEntry(form_frame, textvariable=email_var, width=250, height=35, font=('Arial', 12))
        email_entry.pack()

        # 右侧：头像预览
        avatar_frame = customtkinter.CTkFrame(content_frame, fg_color="transparent")
        avatar_frame.pack(side='right')
        
        avatar_preview = tk.Canvas(avatar_frame, width=120, height=120, bd=0, highlightthickness=0, bg=Theme.get_color('bg_primary'))
        avatar_preview.pack(pady=(0, 15))
        
        try:
            avatar_path = getattr(user, 'avatar_path', None)
            if avatar_path:
                img = load_circular_thumbnail(avatar_path, size=(120, 120))
                if img:
                    avatar_preview.image = img
                    avatar_preview.delete('all')
                    avatar_preview.create_image(60, 60, image=img)
                else:
                    avatar_preview.create_oval(5, 5, 115, 115, outline='#ddd', width=2)
                    avatar_preview.create_text(60, 60, text='👤', font=('Arial', 40), fill=Theme.get_color('fg_tertiary'))
            else:
                avatar_preview.create_oval(5, 5, 115, 115, outline='#ddd', width=2)
                avatar_preview.create_text(60, 60, text='👤', font=('Arial', 40), fill=Theme.get_color('fg_tertiary'))
        except Exception:
            avatar_preview.create_oval(5, 5, 115, 115, outline='#ddd', width=2)
            avatar_preview.create_text(60, 60, text='👤', font=('Arial', 40), fill=Theme.get_color('fg_tertiary'))

        def change_avatar():
            from tkinter import filedialog
            import os, shutil

            file_path = filedialog.askopenfilename(title='Select Avatar Image', filetypes=[('Image', '*.png;*.jpg;*.jpeg;*.gif')])
            if not file_path:
                return

            dm = DataManager()
            avatars_dir = os.path.join(dm.data_dir, 'avatars')
            os.makedirs(avatars_dir, exist_ok=True)
            _, ext = os.path.splitext(file_path)
            dest_name = f"{user.user_id}{ext}"
            dest_path = os.path.join(avatars_dir, dest_name)
            try:
                shutil.copyfile(file_path, dest_path)
                rel_path = os.path.relpath(dest_path)
                self.controller.auth_service.update_user(user.user_id, avatar_path=rel_path)
                # update preview
                try:
                    img2 = load_circular_thumbnail(rel_path, size=(120, 120))
                    if img2:
                        avatar_preview.image = img2
                        avatar_preview.delete('all')
                        avatar_preview.create_image(60, 60, image=img2)
                    else:
                        avatar_preview.delete('all')
                        avatar_preview.create_oval(5, 5, 115, 115, outline='#ddd', width=2)
                        avatar_preview.create_text(60, 60, text='👤', font=('Arial', 40), fill=Theme.get_color('fg_tertiary'))
                except Exception:
                    avatar_preview.delete('all')
                    avatar_preview.create_oval(5, 5, 115, 115, outline='#ddd', width=2)
                    avatar_preview.create_text(60, 60, text='👤', font=('Arial', 40), fill=Theme.get_color('fg_tertiary'))
            except Exception as e:
                messagebox.showerror(t("account.actions.avatar_error"), str(e))

        change_btn = customtkinter.CTkButton(
            avatar_frame,
            text='Change Avatar',
            command=change_avatar,
            width=120,
            height=32,
            font=('Arial', 11)
        )
        change_btn.pack()

        # 按钮
        btn_frame = customtkinter.CTkFrame(frm, fg_color="transparent")
        btn_frame.pack(pady=20)
        
        def save():
            updates = {}
            if name_var.get() and name_var.get() != getattr(user, 'username', ''):
                updates['username'] = name_var.get()
            if email_var.get() and email_var.get() != getattr(user, 'email', ''):
                updates['email'] = email_var.get()
            if updates:
                try:
                    self.controller.auth_service.update_user(user.user_id, **updates)
                except Exception as e:
                    messagebox.showerror(t("common.error"), str(e))
                else:
                    self.update_data()
                    messagebox.showinfo("Success", "Profile updated successfully")
            win.destroy()

        customtkinter.CTkButton(
            btn_frame,
            text='Save',
            command=save,
            width=120,
            height=35,
            font=('Arial', 13, 'bold'),
            fg_color=Theme.get_color('accent'),
            hover_color=Theme.get_color('accent_hover'),
            corner_radius=8
        ).pack(side='left', padx=10)
        
        customtkinter.CTkButton(
            btn_frame,
            text='Cancel',
            command=win.destroy,
            width=120,
            height=35,
            font=('Arial', 13),
            fg_color=("gray70", "gray30"),
            hover_color=("gray60", "gray40"),
            corner_radius=8
        ).pack(side='left', padx=10)
    def upload_avatar(self):
        # Open file dialog to choose an image, copy into data/avatars, update user record
        try:
            from tkinter import filedialog
            import os, shutil

            if not self.controller.auth_service.is_logged_in():
                messagebox.showwarning(t("account.actions.not_logged_in_title"), t("account.actions.login_required_avatar"))
                return

            file_path = filedialog.askopenfilename(title='Select avatar image', filetypes=[('Image', '*.png;*.jpg;*.jpeg;*.gif')])
            if not file_path:
                return

            dm = DataManager()
            avatars_dir = os.path.join(dm.data_dir, 'avatars')
            os.makedirs(avatars_dir, exist_ok=True)

            _, ext = os.path.splitext(file_path)
            user = self.controller.auth_service.current_user
            dest_name = f"{user.user_id}{ext}"
            dest_path = os.path.join(avatars_dir, dest_name)
            shutil.copyfile(file_path, dest_path)

            # Store relative path like data/avatars/xxx.png
            rel_path = os.path.relpath(dest_path)
            try:
                self.controller.auth_service.update_user(user.user_id, avatar_path=rel_path)
            except Exception as e:
                messagebox.showerror(t("account.actions.error_saving_avatar"), str(e))
                return

            messagebox.showinfo(t("account.actions.avatar_uploaded"), t("account.actions.avatar_uploaded_success"))
            # Refresh display
            self.update_data()
        except Exception as e:
            # Keep robust; show error but do not crash
            messagebox.showerror(t("account.actions.avatar_error"), str(e))

    def update_data(self):
        try:
            if self.controller.auth_service.is_logged_in():
                user = self.controller.auth_service.current_user
                self.name_label.configure(text=getattr(user, 'username', 'Guest'))
                email = getattr(user, 'email', '')
                self.email_label.configure(text=email if email else 'Not provided')
            else:
                self.name_label.configure(text='Guest')
                self.email_label.configure(text='Not logged in')

            # Load avatar if available
            try:
                avatar_path = getattr(user, 'avatar_path', None) if self.controller.auth_service.is_logged_in() else None
            except Exception:
                avatar_path = None

            self.avatar_canvas.delete('all')
            if avatar_path:
                try:
                    img = load_circular_thumbnail(avatar_path, size=(120, 120))
                    if img:
                        self._avatar_img = img
                        # create_image will place center at (60,60)
                        self.avatar_canvas.create_image(60, 60, image=img)
                    else:
                        self.avatar_canvas.create_rectangle(2, 2, 118, 118, outline='#ccc')
                        self.avatar_canvas.create_text(60, 60, text='Avatar', fill='#999')
                except Exception:
                    self.avatar_canvas.create_rectangle(2, 2, 118, 118, outline='#ccc')
                    self.avatar_canvas.create_text(60, 60, text='Avatar', fill='#999')
            else:
                self.avatar_canvas.create_rectangle(2, 2, 118, 118, outline='#ccc')
                self.avatar_canvas.create_text(60, 60, text='No Avatar', fill='#999')
        except Exception:
            # Swallow to keep import-time and page-switching robust
            return
    
    def refresh_language(self):
        """刷新语言显示"""
        try:
            # 更新导航栏
            self.back_btn.configure(text=t("common.back"))
            self.logo.configure(text=t("account.logo"))
            
            # 更新用户工具栏
            self.cart_btn.configure(text=t('product.cart'))
            self.orders_btn.configure(text=t('product.orders'))
            self.profile_btn.configure(text=t('product.account'))
            
            # 更新按钮
            self.edit_profile_btn.configure(text=t('account.edit_profile'))
            self.upload_avatar_btn.configure(text=t('account.upload_avatar'))
            self.settings_btn.configure(text=t('account.settings'))
            
            # 更新用户信息显示
            self.update_data()
            
        except Exception as e:
            from core.utils.logger import error
            error(f"Failed to refresh language in AccountPage: {e}")

    def open_settings(self):
        """Open the Settings modal dialog."""
        SettingsDialog(self, self.controller)


class SettingsDialog:
    """Modal settings dialog with a few common user controls.

    Features implemented:
    - Language selection (saved to data/settings.json)
    - Theme selection (light/dark) (saved to data/settings.json)
    - Change password (calls AuthService.change_password)
    - View orders (shows orders.json entries for current user)
    - Logout (calls AuthService.logout and navigates to WelcomePage)
    - Clear remembered login file
    """

    def __init__(self, parent, controller):
        self.parent = parent
        self.controller = controller
        self.dm = DataManager()

        self.top = customtkinter.CTkToplevel(parent)
        self.top.title('Settings')
        self.top.geometry('600x550')
        self.top.transient(parent)
        self.top.grab_set()

        frm = customtkinter.CTkFrame(self.top, fg_color="transparent")
        frm.pack(fill='both', expand=True, padx=20, pady=20)

        # 标题
        title = customtkinter.CTkLabel(
            frm,
            text='⚙️ Settings',
            font=('Arial', 20, 'bold'),
            text_color=Theme.get_color('fg_primary')
        )
        title.pack(pady=(0, 20))
        
        # 创建选项卡控件（暂时保持 ttk.Notebook）
        self.notebook = ttk.Notebook(frm)
        self.notebook.pack(fill='both', expand=True, pady=(0, 15))
        
        # 基础设置选项卡
        self.basic_frame = ttk.Frame(self.notebook, padding=20)
        self.notebook.add(self.basic_frame, text=t("account.settings.basic"))
        
        # Language
        ttk.Label(self.basic_frame, text=t("account.settings.language")).grid(row=0, column=0, sticky='e', pady=5)
        self.lang_var = tk.StringVar(value=self._load_setting('language') or 'zh_CN')
        lang_cb = ttk.Combobox(self.basic_frame, textvariable=self.lang_var, 
                              values=['zh_CN', 'en_US'], state='readonly', width=18)
        lang_cb.grid(row=0, column=1, sticky='w', padx=8, pady=5)

        # Theme
        ttk.Label(self.basic_frame, text=t("account.settings.theme")).grid(row=1, column=0, sticky='e', pady=5)
        self.theme_var = tk.StringVar(value=self._load_setting('theme') or 'light')
        theme_cb = ttk.Combobox(self.basic_frame, textvariable=self.theme_var, 
                               values=['light', 'dark'], state='readonly', width=18)
        theme_cb.grid(row=1, column=1, sticky='w', padx=8, pady=5)
        
        # Font Size
        ttk.Label(self.basic_frame, text=t("account.settings.display.font_size")).grid(row=2, column=0, sticky='e', pady=5)
        self.font_size_var = tk.StringVar(value=self._load_setting('font_size') or 'medium')
        font_size_cb = ttk.Combobox(self.basic_frame, textvariable=self.font_size_var, 
                                   values=['small', 'medium', 'large'], state='readonly', width=18)
        font_size_cb.grid(row=2, column=1, sticky='w', padx=8, pady=5)
        
        # 通知设置选项卡
        self.notifications_frame = ttk.Frame(self.notebook, padding=10)
        self.notebook.add(self.notifications_frame, text=t("account.settings.notifications.title"))
        
        # 通知选项
        self.order_notifications = tk.BooleanVar(value=self._load_setting('order_notifications', True))
        ttk.Checkbutton(self.notifications_frame, text=t("account.settings.notifications.order_notifications"), 
                       variable=self.order_notifications).grid(row=0, column=0, sticky='w', pady=5)
        
        self.promotion_notifications = tk.BooleanVar(value=self._load_setting('promotion_notifications', True))
        ttk.Checkbutton(self.notifications_frame, text=t("account.settings.notifications.promotion_notifications"), 
                       variable=self.promotion_notifications).grid(row=1, column=0, sticky='w', pady=5)
        
        self.stock_notifications = tk.BooleanVar(value=self._load_setting('stock_notifications', False))
        ttk.Checkbutton(self.notifications_frame, text=t("account.settings.notifications.stock_notifications"), 
                       variable=self.stock_notifications).grid(row=2, column=0, sticky='w', pady=5)
        
        # 隐私设置选项卡
        self.privacy_frame = ttk.Frame(self.notebook, padding=10)
        self.notebook.add(self.privacy_frame, text=t("account.settings.privacy.title"))
        
        # 隐私选项
        ttk.Button(self.privacy_frame, text=t("account.settings.privacy.clear_browse_history"), 
                  command=self.clear_browse_history).grid(row=0, column=0, sticky='w', pady=5)
        
        ttk.Button(self.privacy_frame, text=t("account.settings.privacy.clear_cache"), 
                  command=self.clear_cache).grid(row=1, column=0, sticky='w', pady=5)
        
        ttk.Button(self.privacy_frame, text=t("account.settings.privacy.clear_search_history"), 
                  command=self.clear_search_history).grid(row=2, column=0, sticky='w', pady=5)
        
        # 显示设置选项卡
        self.display_frame = ttk.Frame(self.notebook, padding=10)
        self.notebook.add(self.display_frame, text=t("account.settings.display.title"))
        
        # 每页商品数量
        ttk.Label(self.display_frame, text=t("account.settings.display.products_per_page")).grid(row=0, column=0, sticky='e', pady=5)
        self.products_per_page_var = tk.StringVar(value=self._load_setting('products_per_page') or '9')
        products_cb = ttk.Combobox(self.display_frame, textvariable=self.products_per_page_var, 
                                  values=['6', '9', '12'], state='readonly', width=18)
        products_cb.grid(row=0, column=1, sticky='w', padx=8, pady=5)
        
        # 商品卡片尺寸
        ttk.Label(self.display_frame, text=t("account.settings.display.card_size")).grid(row=1, column=0, sticky='e', pady=5)
        self.card_size_var = tk.StringVar(value=self._load_setting('card_size') or 'medium')
        card_size_cb = ttk.Combobox(self.display_frame, textvariable=self.card_size_var, 
                                   values=['small', 'medium', 'large'], state='readonly', width=18)
        card_size_cb.grid(row=1, column=1, sticky='w', padx=8, pady=5)
        
        # 数据管理选项卡
        self.data_frame = ttk.Frame(self.notebook, padding=10)
        self.notebook.add(self.data_frame, text=t("account.settings.data.title"))
        
        # 数据导出选项
        ttk.Button(self.data_frame, text=t("account.settings.data.export_orders"), 
                  command=self.export_orders).grid(row=0, column=0, sticky='w', pady=5)
        
        ttk.Button(self.data_frame, text=t("account.settings.data.export_cart"), 
                  command=self.export_cart).grid(row=1, column=0, sticky='w', pady=5)
        
        ttk.Button(self.data_frame, text=t("account.settings.data.export_user_data"), 
                  command=self.export_user_data).grid(row=2, column=0, sticky='w', pady=5)

        # Buttons column
        btn_frame = customtkinter.CTkFrame(frm, fg_color="transparent")
        btn_frame.pack(pady=(15, 10))

        customtkinter.CTkButton(
            btn_frame, 
            text=t("account.settings.save_settings"), 
            command=self.save_settings,
            width=130,
            height=35,
            font=('Arial', 12, 'bold'),
            fg_color=Theme.get_color('accent'),
            hover_color=Theme.get_color('accent_hover'),
            corner_radius=8
        ).pack(side='left', padx=6)
        
        customtkinter.CTkButton(
            btn_frame, 
            text=t("account.settings.change_password"), 
            command=self.change_password,
            width=130,
            height=35,
            font=('Arial', 12),
            fg_color=("gray70", "gray30"),
            hover_color=("gray60", "gray40"),
            corner_radius=8
        ).pack(side='left', padx=6)
        
        customtkinter.CTkButton(
            btn_frame, 
            text=t("account.settings.view_orders"), 
            command=self.view_orders,
            width=130,
            height=35,
            font=('Arial', 12),
            fg_color=("gray70", "gray30"),
            hover_color=("gray60", "gray40"),
            corner_radius=8
        ).pack(side='left', padx=6)

        # Dangerous / account actions
        sec_frame = customtkinter.CTkFrame(frm, fg_color="transparent")
        sec_frame.pack(pady=(0, 10))
        
        customtkinter.CTkButton(
            sec_frame, 
            text=t("account.settings.logout"), 
            command=self.logout,
            width=150,
            height=35,
            font=('Arial', 12, 'bold'),
            fg_color=Theme.get_color('error'),
            hover_color="#C0392B",
            corner_radius=8
        ).pack(side='left', padx=8)
        
        customtkinter.CTkButton(
            sec_frame, 
            text=t("account.settings.clear_remembered"), 
            command=self.clear_remembered,
            width=180,
            height=35,
            font=('Arial', 12),
            fg_color=("gray70", "gray30"),
            hover_color=("gray60", "gray40"),
            corner_radius=8
        ).pack(side='left', padx=8)

        customtkinter.CTkButton(
            frm, 
            text=t("account.settings.close"), 
            command=self.close,
            width=100,
            height=35,
            font=('Arial', 13),
            fg_color=("gray70", "gray30"),
            hover_color=("gray60", "gray40"),
            corner_radius=8
        ).pack(pady=(10, 0))

    # ---- settings persistence helpers ----
    def _settings_file(self):
        return self.dm._get_file_path('settings.json')

    def _load_setting(self, key, default=None):
        try:
            data = self.dm.load_data('settings.json')
            if isinstance(data, dict):
                return data.get(key, default)
        except Exception:
            return default

    def _save_settings_dict(self, d):
        # allow replacing or creating dict
        try:
            cur = {}
            if isinstance(self.dm.load_data('settings.json'), dict):
                cur = self.dm.load_data('settings.json')
            cur.update(d)
            self.dm.save_data('settings.json', cur)
        except Exception:
            # fallback: write minimal dict
            try:
                self.dm.save_data('settings.json', d)
            except Exception:
                pass

    # ---- actions ----
    def save_settings(self):
        # Collect all settings
        settings = {
            'language': self.lang_var.get(),
            'theme': self.theme_var.get(),
            'font_size': self.font_size_var.get(),
            'order_notifications': self.order_notifications.get(),
            'promotion_notifications': self.promotion_notifications.get(),
            'stock_notifications': self.stock_notifications.get(),
            'products_per_page': self.products_per_page_var.get(),
            'card_size': self.card_size_var.get()
        }
        
        # Save settings
        self._save_settings_dict(settings)
        
        # Apply theme and font settings
        try:
            Theme.set_theme(settings['theme'])
            Theme.set_font_size(settings['font_size'])
        except Exception as e:
            from core.utils.logger import error
            error(f"Failed to apply theme/font settings: {e}")
        
        # Refresh product page display settings
        try:
            if hasattr(self.controller, 'pages') and 'ProductPage' in self.controller.pages:
                product_page = self.controller.pages['ProductPage']
                if hasattr(product_page, 'refresh_display_settings'):
                    product_page.refresh_display_settings()
        except Exception as e:
            from core.utils.logger import error
            error(f"Failed to refresh product page display settings: {e}")
        
        # If language changed, refresh all pages
        if settings['language'] != self._load_setting('language'):
            try:
                self.controller.change_language(settings['language'])
                # Refresh current settings dialog text
                self.refresh_dialog_text()
            except Exception as e:
                from core.utils.logger import error
                error(f"Failed to change language: {e}")

        messagebox.showinfo(t("account.settings.title"), t("account.settings.settings_saved"))

    def refresh_dialog_text(self):
        """Refresh settings dialog text"""
        try:
            # Refresh tab titles
            self.notebook.tab(0, text=t("account.settings.basic"))
            self.notebook.tab(1, text=t("account.settings.notifications.title"))
            self.notebook.tab(2, text=t("account.settings.privacy.title"))
            self.notebook.tab(3, text=t("account.settings.display.title"))
            self.notebook.tab(4, text=t("account.settings.data.title"))
            
            # Refresh button text
            # You can add more text elements to refresh here
        except Exception as e:
            from core.utils.logger import error
            error(f"Failed to refresh dialog text: {e}")

    def change_password(self):
        if not self.controller.auth_service.is_logged_in():
            messagebox.showwarning(t("account.actions.not_logged_in_title"), t("account.actions.login_required_password"))
            return
        # simple password change dialog
        from tkinter import simpledialog

        old = simpledialog.askstring('Change password', 'Current password:', show='*', parent=self.top)
        if old is None:
            return
        new = simpledialog.askstring('Change password', 'New password (at least 6 characters):', show='*', parent=self.top)
        if new is None:
            return
        try:
            self.controller.auth_service.change_password(self.controller.auth_service.current_user.user_id, old, new)
        except Exception as e:
            messagebox.showerror(t("account.settings.change_password"), str(e))
        else:
            messagebox.showinfo(t("account.settings.change_password"), t("account.actions.password_changed"))

    def view_orders(self):
        if not self.controller.auth_service.is_logged_in():
            messagebox.showwarning(t("account.actions.not_logged_in_title"), t("account.actions.login_required_orders"))
            return
        orders = self.dm.load_data('orders.json') or []
        uid = self.controller.auth_service.current_user.user_id
        user_orders = [o for o in orders if o.get('user_id') == uid]

        win = tk.Toplevel(self.top)
        win.title('My Orders')
        win.geometry('700x500')
        win.resizable(True, True)
        frm = ttk.Frame(win, padding=8)
        frm.pack(fill='both', expand=True)

        if not user_orders:
            ttk.Label(frm, text=t("account.actions.no_orders_found")).pack()
            return

        text = tk.Text(frm, wrap='word')
        text.pack(fill='both', expand=True)
        for o in user_orders:
            text.insert('end', f"{t('account.order_details.order_id')}: {o.get('order_id', '<unknown>')}\n")
            text.insert('end', f"{t('account.order_details.items')}: {o.get('items', [])}\n")
            text.insert('end', f"{t('account.order_details.total')}: {o.get('total', 0)}\n")
            text.insert('end', f"{t('account.order_details.created_at')}: {o.get('created_at', '')}\n")
            text.insert('end', t('account.order_details.separator') + '\n')
        text.configure(state='disabled')

    def logout(self):
        try:
            self.controller.auth_service.logout()
            # Update cart to guest mode
            self.controller.update_cart_user()
        except Exception:
            pass
        messagebox.showinfo(t("account.settings.logout"), t("account.actions.logged_out"))
        try:
            self.controller.show_page('WelcomePage')
        except Exception:
            pass
        self.close()

    def clear_remembered(self):
        try:
            # AuthService exposes a private helper but it's safe to call here
            self.controller.auth_service._clear_remembered()
        except Exception as e:
            messagebox.showerror(t("common.error"), str(e))
            return
        messagebox.showinfo(t("account.settings.clear_remembered"), t("account.actions.remembered_cleared"))

    def clear_browse_history(self):
        """Clear browse history"""
        try:
            # Clear browse history data (if any)
            # This can clear user access page records
            browse_history_file = self.dm._get_file_path('browse_history.json')
            if os.path.exists(browse_history_file):
                os.remove(browse_history_file)
            
            # 清除产品详情页面缓存
            if hasattr(self.controller, 'detail_page_cache'):
                self.controller.detail_page_cache.clear()
            
            messagebox.showinfo(t("common.success"), t("account.settings.privacy.browse_history_cleared"))
        except Exception as e:
            messagebox.showerror(t("common.error"), t("account.settings.privacy.clear_failed", error=str(e)))
    
    def clear_cache(self):
        """Clear cache data"""
        try:
            import shutil
            
            # Clear image cache directories
            cache_dirs = [
                os.path.join(self.dm.data_dir, 'cache'),
                os.path.join(self.dm.data_dir, 'temp'),
                os.path.join(self.dm.data_dir, 'thumbnails')
            ]
            
            cleared_count = 0
            for cache_dir in cache_dirs:
                if os.path.exists(cache_dir):
                    shutil.rmtree(cache_dir)
                    cleared_count += 1
            
            # Clear product detail page cache
            if hasattr(self.controller, 'detail_page_cache'):
                self.controller.detail_page_cache.clear()
            
            messagebox.showinfo(t("common.success"), t("account.settings.privacy.cache_cleared", count=cleared_count))
        except Exception as e:
            messagebox.showerror(t("common.error"), t("account.settings.privacy.clear_failed", error=str(e)))
    
    def clear_search_history(self):
        """Clear search history"""
        try:
            import os
            
            # Clear search history file
            search_history_file = self.dm._get_file_path('search_history.json')
            if os.path.exists(search_history_file):
                os.remove(search_history_file)
            
            # If product page has search history, clear it too
            if hasattr(self.controller, 'pages') and 'ProductPage' in self.controller.pages:
                product_page = self.controller.pages['ProductPage']
                if hasattr(product_page, 'search_history'):
                    product_page.search_history = []
                if hasattr(product_page, 'search_var'):
                    product_page.search_var.set('')
            
            messagebox.showinfo(t("common.success"), t("account.settings.privacy.search_history_cleared"))
        except Exception as e:
            messagebox.showerror(t("common.error"), t("account.settings.privacy.clear_failed", error=str(e)))
    
    def export_orders(self):
        """Export order history"""
        try:
            from tkinter import filedialog
            import json
            from datetime import datetime
            
            # Get order data
            orders = self.dm.load_data('orders.json') or []
            
            # Select save location
            filename = filedialog.asksaveasfilename(
                defaultextension=".json",
                filetypes=[("JSON files", "*.json"), ("All files", "*.*")],
                title=t("account.data.export_orders_title")
            )
            
            if filename:
                # Add export timestamp
                export_data = {
                    'export_time': datetime.now().isoformat(),
                    'orders': orders
                }
                
                with open(filename, 'w', encoding='utf-8') as f:
                    json.dump(export_data, f, ensure_ascii=False, indent=2)
                
                messagebox.showinfo(t("common.success"), t("account.settings.data.export_success", type=t("account.settings.data.orders"), path=filename))
        except Exception as e:
            messagebox.showerror(t("common.error"), t("account.settings.data.export_failed", error=str(e)))
    
    def export_cart(self):
        """Export cart data"""
        try:
            from tkinter import filedialog
            import json
            from datetime import datetime
            
            # Get cart data
            cart_data = {
                'items': [{'product_id': item.product.product_id, 'name': item.product.name, 
                          'quantity': item.quantity, 'price': item.product.price} 
                         for item in self.controller.shopping_cart.items],
                'total_items': self.controller.shopping_cart.total_items,
                'total_price': self.controller.shopping_cart.total_price
            }
            
            # 选择保存位置
            filename = filedialog.asksaveasfilename(
                defaultextension=".json",
                filetypes=[("JSON files", "*.json"), ("All files", "*.*")],
                title=t("account.data.export_cart_title")
            )
            
            if filename:
                export_data = {
                    'export_time': datetime.now().isoformat(),
                    'cart': cart_data
                }
                
                with open(filename, 'w', encoding='utf-8') as f:
                    json.dump(export_data, f, ensure_ascii=False, indent=2)
                
                messagebox.showinfo(t("common.success"), t("account.settings.data.export_success", type=t("account.settings.data.cart"), path=filename))
        except Exception as e:
            messagebox.showerror(t("common.error"), t("account.settings.data.export_failed", error=str(e)))
    
    def export_user_data(self):
        """Export user data"""
        try:
            from tkinter import filedialog
            import json
            from datetime import datetime
            
            if not self.controller.auth_service.is_logged_in():
                messagebox.showwarning(t("account.settings.not_logged_in"), t("account.settings.not_logged_in_message"))
                return
            
            # Get user data
            user = self.controller.auth_service.current_user
            user_data = {
                'user_id': getattr(user, 'user_id', ''),
                'username': getattr(user, 'username', ''),
                'email': getattr(user, 'email', ''),
                'avatar_path': getattr(user, 'avatar_path', ''),
                'created_at': getattr(user, 'created_at', '')
            }
            
            # 选择保存位置
            filename = filedialog.asksaveasfilename(
                defaultextension=".json",
                filetypes=[("JSON files", "*.json"), ("All files", "*.*")],
                title=t("account.data.export_user_title")
            )
            
            if filename:
                export_data = {
                    'export_time': datetime.now().isoformat(),
                    'user_data': user_data
                }
                
                with open(filename, 'w', encoding='utf-8') as f:
                    json.dump(export_data, f, ensure_ascii=False, indent=2)
                
                messagebox.showinfo(t("common.success"), t("account.settings.data.export_success", type=t("account.settings.data.user_data"), path=filename))
        except Exception as e:
            messagebox.showerror(t("common.error"), t("account.settings.data.export_failed", error=str(e)))

    def close(self):
        try:
            self.top.grab_release()
        except Exception:
            pass
        self.top.destroy()
